﻿package kizzo.game 
{		
	import flash.events.Event;
	import kizzo.game.tile_objects.ActivatedTile;
	import kizzo.game.tile_objects.ActivatorTile;
	import kizzo.game.tile_objects.TileObject;
	import org.flashdevelop.utils.FlashConnect;

	public class TileState
	{	
		public var value:uint;
		
		protected var objects:Vector.<TileObject>;
		
		protected var _has_tile:Boolean;
		protected var _has_cube:Boolean;
		
		public static const EMPTY:uint 						= 0x00000000;
		public static const SIMPLE_TILE:uint 				= 0x00000001;
		public static const MASTER_CUBE:uint 				= 0x00000002;
		public static const MASTER_GOAL:uint 				= 0x00000004;
		public static const SLAVE_CUBE_A:uint 				= 0x00000008;
		public static const SLAVE_GOAL_A:uint 				= 0x00000010;
		public static const SLAVE_LINK_A:uint				= 0x00000020;
		public static const ROTATE_CLOCKWISE_MOD:uint		= 0x00000040;
		public static const BOOST_MOD:uint					= 0x00000080;
		public static const NEGATOR_TILE:uint				= 0x00000100;
		public static const BLOCKER_CUBE:uint				= 0x00000200;
		public static const CRUMBLING_TILE:uint				= 0x00000400;
		public static const TELEPORT_TILE:uint				= 0x00000800;
		public static const SLAVE_CUBE_B:uint				= 0x00001000;
		public static const SLAVE_GOAL_B:uint				= 0x00002000;
		public static const SLAVE_LINK_B:uint				= 0x00004000;
		public static const MIRROR_Z:uint					= 0x00008000;
		public static const MIRROR_X:uint					= 0x00010000;
		public static const REMOVE_LINK:uint				= 0x00020000;
		public static const REMOVE_MODS:uint				= 0x00040000;
		public static const ACTIVATOR:uint					= 0x00080000;
		public static const ACTIVATED:uint					= 0x00100000;				
		public static const REPULSOR:uint					= 0x00200000;
		
		
		public static var tiles:Vector.<uint> = new <uint>	[	SIMPLE_TILE, MASTER_GOAL, SLAVE_GOAL_A, SLAVE_LINK_A, ROTATE_CLOCKWISE_MOD, BOOST_MOD, 
																NEGATOR_TILE, BLOCKER_CUBE, CRUMBLING_TILE, TELEPORT_TILE, SLAVE_GOAL_B, SLAVE_LINK_B, 
																MIRROR_X, MIRROR_Z, ACTIVATED, ACTIVATOR, REPULSOR];
																
		public static var cubes:Vector.<uint> = new <uint> 	[	MASTER_CUBE, SLAVE_CUBE_A, SLAVE_CUBE_B, BLOCKER_CUBE];
		
		
		public var potential_moves:Vector.<PotentialMove>;
		
		
		public function TileState(val:uint = 0) 
		{
			this.value = val;
			this.objects = new Vector.<TileObject>();
			this.potential_moves = new Vector.<PotentialMove>();
			
			_has_tile = false;
		}
		
		
		public function tile_dispatch_cube_event(e:Event):void
		{			
			for (var i:int = 0; i < this.objects.length; i++)
			{
				if (objects[i].is_tile())
					objects[i].dispatchEvent(e);
			}
		}
		
		
		public function has_flag(flag_mask:uint):Boolean
		{
			return Boolean(value & flag_mask);
		}
		
		
		public function set_flag(flag_mask:uint):void
		{
			this.value |= flag_mask;
				
			if (tiles.indexOf(flag_mask) != -1)
				_has_tile = true;
				
			if (cubes.indexOf(flag_mask) != -1)
				_has_cube = true;				
		}
		
		
		public function clear_flag(flag_mask:uint):void
		{
			this.value &= (~flag_mask);

			if (tiles.indexOf(flag_mask) != -1)
				_has_tile = false;			
				
			if (cubes.indexOf(flag_mask) != -1)
				_has_cube = false;					
		}
		
		
		public function reset():void
		{
			this.value = TileState.EMPTY;
			_has_tile = false;
			_has_cube = false;
		}
		
		
		public function is_free():Boolean
		{
			return !_has_cube;
		}
		
		
		public function has_tile():Boolean
		{
			return _has_tile;
		}
		
		
		public function is_empty():Boolean
		{
			return !Boolean(this.value);
		}
		
		
		public function has_cube():Boolean
		{
			var has_cube:Boolean = false;
			if (this.has_flag(MASTER_CUBE) || this.has_flag(SLAVE_CUBE_A) || this.has_flag(BLOCKER_CUBE))
				has_cube = true;
			return has_cube;			
		}
		
		
		public function add_object(obj:TileObject):void
		{			
			Main.get_instance().object_list.push(obj);
			this.set_flag(obj.type);
			this.objects.push(obj);
		}
		
		
		public function get_objects():Vector.<TileObject>
		{
			return this.objects;
		}
		
		
		public function clear_objects():void
		{
			this.objects = new Vector.<TileObject>();
		}
		
		
		public function get_object_by_type(type:uint):TileObject
		{
			for (var i:uint = 0; i < this.objects.length; i++)
			{								
				var obj:TileObject = this.objects[i];				
				if (obj.type == type)
					break;
			}
			return objects.splice(i,1)[0];
		}
				
		
		public function get_object_ref_by_type(type:uint):TileObject
		{
			for (var i:uint = 0; i < this.objects.length; i++)
			{								
				var obj:TileObject = this.objects[i];				
				if (obj.type == type)
					break;
			}
			return obj;
		}		
	
		
		}
}